package com.hust.yuqian.dcts;

/**
 * Created by mmutuyu on 14-1-10.
 */

/*
 ****************************************************************************
 *
 * Forward Discrete Cosine Transform (FDCT) 离散余弦正变换, 可看作一个谐波分析仪
 * From: http://www.cyut.edu.tw/~yltang/utility.html
 ****************************************************************************
 */

public class FDct {

    /**
     *
     * @param nrows 原始图像行数
     * @param ncols 原始图像列数
     * @param b 原始图像的'b'值数组
     * @return 原始图片DCT转换后的矩阵
     */
    public static double[][] operation(int nrows, int ncols, int[][] b){
        final int N = 8;  // Block size
        int m, n, x, y, u, v;
        double  in[][], dct[][], sum, au, av;
        double  n1 = Math.sqrt(1.0/N), n2 = Math.sqrt(2.0/N);

        if (nrows%N!=0 || ncols%N!=0) {
            System.out.println("Nrows and ncols should be multiples of 8");
            System.exit(0);
        }

        in = new double[nrows][ncols];
        dct = new double[nrows][ncols];

        // For each NxN block[m,n]
        for (m=0; m<nrows; m+=N) {
            for (n=0; n<ncols; n+=N) {

                // For each pixel[u,v] in block[m,n]
                for (u=m; u<m+N; u++) {
                    au = (u==m)? n1: n2;
                    for (v=n; v<n+N; v++) {
                        av = (v==n)? n1: n2;

                        // Sum up all pixels in the block
                        for (x=m, sum=0; x<m+N; x++) {
                            for (y=n; y<n+N; y++) {
                                in[x][y] = b[x][y] - 128.0;  // Subtract by 128
                                sum += in[x][y] * Math.cos((2*(x-m)+1)*(u-m)*Math.PI/(2*N)) *
                                        Math.cos((2*(y-n)+1)*(v-n)*Math.PI/(2*N));
                            }
                        }
                        dct[u][v] = au * av * sum;

                    } // for v
                } // for u

            }  // for n
        }  // for m

        return dct;
    }

}
